<?php
/**
 * functions.php
 * 常用函数
 */

/**
 * 获取 http 请求参数
 */
function getgpc ($k, $type = 'GET')
{
    $type = strtoupper($type);
    switch ($type) {
        case 'GET':
            $var = &$_GET;
            break;
        case 'POST':
            $var = &$_POST;
            break;
        case 'COOKIE':
            $var = &$_COOKIE;
            break;
        default:
            if (isset($_GET[$k])) {
                $var = &$_GET;
            } else {
                $var = &$_POST;
            }
            break;
    }

    return isset($var[$k]) ? $var[$k] : NULL;
}

/**
 * 解析路由
 */
function parse_path ($path)
{
    if (empty($path)) {
        return FALSE;
    }
    $route = explode("/", $path);
    if (empty($route)) {
        return FALSE;
    }
    return $route;
}

// json结果返回
function data_format_json ($error_code = "0", $content = array())
{
    $data = array();
    $data['ret'] = (string) $error_code;
    $data['msg'] = $content;
    echo json_encode($data);
    exit();
}

function archive_loader ($class)
{
    $route_info = (require INTERFACE_PATH . '/config/route.conf.php');
    if (empty($route_info[$class])) {
        throw new Exception('class '. $class .' not exists', 500);
    }
    include INTERFACE_PATH . "/" . $route_info[$class];
}

// 加密函数
function archive_encrypt ($data, $key = "36f11f0cfa2689!@#ZXC")
{
    $key = md5($key);
    $x = 0;
    $len = strlen($data);
    $l = strlen($key);
    $char = '';
    for ($i = 0; $i < $len; $i ++) {
        if ($x == $l) {
            $x = 0;
        }
        $char .= $key{$x};
        $x ++;
    }
    $str = '';
    for ($i = 0; $i < $len; $i ++) {
        $str .= chr(ord($data{$i}) + (ord($char{$i})) % 256);
    }
    return base64_encode($str);
}

function archive_decrypt ($data, $key = "36f11f0cfa2689!@#ZXC")
{
    $key = md5($key);
    $x = 0;
    $data = base64_decode($data);
    $len = strlen($data);
    $l = strlen($key);
    $char = '';
    for ($i = 0; $i < $len; $i ++) {
        if ($x == $l) {
            $x = 0;
        }
        $char .= substr($key, $x, 1);
        $x ++;
    }
    $str = '';
    for ($i = 0; $i < $len; $i ++) {
        if (ord(substr($data, $i, 1)) < ord(substr($char, $i, 1))) {
            $str .= chr((ord(substr($data, $i, 1)) + 256) - ord(substr($char, $i, 1)));
        } else {
            $str .= chr(ord(substr($data, $i, 1)) - ord(substr($char, $i, 1)));
        }
    }
    return $str;
}

function http_post ($url, $data = '')
{
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    curl_setopt($ch, CURLOPT_TIMEOUT, 10); // 最多10秒 超过10超时
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Content-Type: application/json',
        'Content-Length: ' . strlen($data)
    ));
    $result = curl_exec($ch);
    curl_close($ch);
    return $result;
}

// php curl GET 方法
function http_get ($url)
{ // 模拟获取内容函数
    $ua = "clipcloud://v1.0.0(Linux;v0.01;zh_cn;)";
    $curl = curl_init(); // 启动一个CURL会话
    curl_setopt($curl, CURLOPT_URL, $url); // 要访问的地址
    curl_setopt($curl, CURLOPT_USERAGENT, $ua); // 模拟用户使用的浏览器
    curl_setopt($curl, CURLOPT_HTTPGET, 1); // 发送一个常规的GET请求
    curl_setopt($curl, CURLOPT_TIMEOUT, 10); // 最多10秒 超过10超时
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // 获取的信息以文件流的形式返回
    $output = curl_exec($curl); // 执行操作
    if (curl_errno($curl)) {
        data_format_json(- 100, 'Errno' . curl_error($curl));
    }
    curl_close($curl); // 关闭CURL会话
    return $output; // 返回数据
}

/**
 * 记录日志函数
 */
function log_level ($desc = "", $type = 0, $file_pre = 'clipcloud_', $append_msg = 'the array is:')
{
    if (! LOG_SWITCH) {
        return;
    }
    if (is_array($desc)) {
        $desc = $append_msg . print_r($desc, TRUE);
    }
    static $class_log = false;
    if (isset($class_log) && empty($class_log)) {
        require_once INTERFACE_PATH . "/lib/Log.class.php";
        $class_log = Log::get_instance();
    }
    $class_log->log($desc, $type, $file_pre);
}

/**
 * ajax 返回
 */
function ajax_return ($data)
{
    header('Content-Type:application/json; charset=utf-8');
    exit(json_encode($data));
}

/**
 * 获取文件的地址
 *
 * @param string $filepath 文件路径
 * @param string $delimiter 是否多个并进行分割
 * @return string/array
 */
function getAttachmentUrl ($filepath, $delimiter = false)
{
    $config = (require INTERFACE_PATH . '/config/uploadfile.conf.php');
    $domain = $config['upload_cdn'];

    if (empty($filepath)) {
        return '';
    }

    if ($delimiter) {
        $filepath = explode('|', $filepath);
    }

    if (is_array($filepath)) {
        foreach ($filepath as $k => $v) {
            if (false === strpos($v, $config['upload_url'] . '/')) {
                $filepath[$k] = $domain . $config['upload_url'] . $v;
            } else {
                $filepath[$k] = $domain . $v;
            }
        }
    } else {
        if (false === strpos($filepath, $config['upload_url'] . '/')) {
            $filepath = $domain . $config['upload_url'] . $filepath;
        } else {
            $filepath = $domain . $filepath;
        }
    }
    return $filepath;
}

/**
 * 容器
 */
function Mg()
{
    require_once INTERFACE_PATH . '/lib/MgContainer.class.php';

    return Container::instance();
}

/**
 * 文件重命名
 *
 * @param integer $userid 用户 ID
 * @param string $title 上传时的文件名称
 * @param string $folder_hid 所属目录的节点序列
 * @return string|boolean
 */
function renameFile($userid, $title, $folder_hid = '0')
{
    if (! $userid || ! $title) {
        return false;
    }

    /* 拆解文件名称为名称和后缀 */
    $suffix = strrchr($title, '.');
    $title_pre = substr($title, 0, strrpos($title, '.'));

    /* 检查名称是否是以复制性标识结尾，即括弧夹数字的形式 */
    if ($check_copy = preg_match('/(.*)\((\d+)\)$/', $title_pre, $matched)) {
        $title_simple = $matched[1];
    } else {
        $title_simple = $title_pre;
    }

    /* mongo 实例化 */
    include INTERFACE_PATH . '/c0/BaseMongo.class.php';
    $baseMongo = new BaseMongo();
    $class_mogondb = $baseMongo->get_mongoInstance();
    $collection_attachment = $class_mogondb->collection('attachment_juna');

    /* 查询该用户的当前目录下的同名文件信息 */
    $where = array('userid' => $userid, 'type' => 1, 'folder_hid' => $folder_hid,
        'title_simple' => $title_simple, 'suffix' => $suffix);
    $juna_info = $collection_attachment->find($where)->toArray();
    $juna_info = json_decode(json_encode($juna_info), true);

    if (empty($juna_info)) {
        /* 若文件信息不存在，则直接返回上传时的文件名称 */
        $title_new = $title;
    } else {
        /* 若文件信息存在，则重新计算新的文件名称 */
        $copy_nums = explode(',', $juna_info[0]['copy_nums']);
        sort($copy_nums); // 排序

        /* 先进行差集比较 */
        if ($check_copy) {
            $copy_nums_new = array_merge($copy_nums, array($matched[2])); // 对新上传的复制标识位数字进行合并
            $copy_nums_new = array_unique($copy_nums_new); // 去重
            $copy_nums_diff = array_diff($copy_nums_new, $copy_nums); // 求差集

            if (! empty($copy_nums_diff)) {
                $title_new = $title_simple . '(' . current($copy_nums_diff) . ')' . $suffix;
            }
        } else {
            if ($copy_nums[0] != -1) {
                $title_new = $title_simple;
            }
        }

        /* 差集比较无果，统一处理 */
        if (! isset($title_new) || ! $title_new) {
            if (count($copy_nums) == 0) {
                $title_new = $title_simple . '(1)' . $suffix;
            } elseif (count($copy_nums) == 1) {
                if ($copy_nums[0] == 1) {
                    $title_new = $title_simple . '(2)' . $suffix;
                } else {
                    $title_new = $title_simple . '(1)' . $suffix;
                }
            } else {
                foreach ($copy_nums as $k => $v) {
                    if ($k == 0 && $v > 1) {
                        $title_new = $title_simple . '(1)' . $suffix;
                        break;
                    } elseif ($k > 0 && $v - $copy_nums[$k - 1] > 1) {
                        if ($copy_nums[$k - 1] < 0) {
                            unset($copy_nums[$k - 1]);
                            $copy_num_new = self::_repeatCal($copy_nums);
                            $title_new = $title_simple . '(' . $copy_num_new . ')' . $suffix;
                        } else{
                            $title_new = $title_simple . '(' . ($copy_nums[$k - 1] + 1) . ')' . $suffix;
                        }
                        break;
                    } elseif ($k == count($copy_nums) - 1 && $v - $copy_nums[$k - 1] == 1) {
                        $title_new = $title_simple . '(' . ($v + 1) . ')' . $suffix;
                        break;
                    }
                }
            }
        }
    }

    return $title_new;
}

/**
 * 二次计算复制标识数字位
 */
function _repeatCal($copy_nums)
{
    sort($copy_nums); // 排序
    if (count($copy_nums) == 1) {
        if ($copy_nums[0] == 1) {
            $copy_num_new = 2;
        } else {
            $copy_num_new = 1;
        }
    } else {
        foreach ($copy_nums as $k => $v) {
            if ($k == 0 && $v > 1) {
                $copy_num_new = 1;
                break;
            } elseif ($k > 0 && $v - $copy_nums[$k - 1] > 1) {
                $copy_num_new = $copy_nums[$k - 1] + 1;
                break;
            } elseif ($k == count($copy_nums) - 1 && $v - $copy_nums[$k - 1] == 1) {
                $copy_num_new = $v + 1;
                break;
            }
        }
    }

    return isset($copy_num_new) ? $copy_num_new : end($copy_nums) + 1;
}

/**
 * 更新复制标识的数字位信息
 *
 * @param integer $userid 用户 ID
 * @param string $title 重命名后的文件（夹）名称
 * @param integer $type 类型。1：文件；2：文件夹；
 * @param string $folder_hid 所属目录的节点序列
 * @return string|boolean
 */
function updateAttachmentCopyNums($userid, $title, $type = 1, $folder_hid = '0')
{
    if (! $userid || ! $title) {
        return false;
    }

    /* 拆解文件名称为名称和后缀 */
    $suffix = strrchr($title, '.');
    $title_pre = substr($title, 0, strrpos($title, '.'));
    if ($type == 2) {
        $title_pre = $title;
    }

    /* 检查名称是否是以复制性标识结尾，即括弧夹数字的形式 */
    if ($check_copy = preg_match('/(.*)\((\d+)\)$/', $title_pre, $matched)) {
        $title_simple = $matched[1];
        $num_add = $matched[2];
    } else {
        $title_simple = $title_pre;
        $num_add = -1;
    }

    /* mongo 实例化 */
    include INTERFACE_PATH . '/c0/BaseMongo.class.php';
    $baseMongo = new BaseMongo();
    $class_mogondb = $baseMongo->get_mongoInstance();
    $collection_attachment = $class_mogondb->collection('attachment_juna');

    /* 查询该用户下的同名文件信息 */
    $where = array('userid' => $userid, 'type' => $type, 'folder_hid' => $folder_hid, 'title_simple' => $title_simple);
    if ($type == 1) {
        $where['suffix'] = $suffix;
    }
    $juna_info = $collection_attachment->find($where)->toArray();
    $juna_info = json_decode(json_encode($juna_info), true);

    if (! empty($juna_info)) { // 存在，则执行更新操作
        /* 处理复制标识的数字位记录 */
        $copy_nums_new = $juna_info[0]['copy_nums'] . ',' . $num_add;
        $copy_nums_new = explode(',', $copy_nums_new);
        sort($copy_nums_new); // 排序
        $copy_nums_new = array_unique($copy_nums_new); // 去重
        $copy_nums_new = implode(',', $copy_nums_new);

        /* 执行更新 */
        $where_update = array('_id' => $juna_info[0]['_id']);
        $set = array('copy_nums' => $copy_nums_new);
        $collection_attachment->where($where_update)->update($set);
    } else { // 不存在，则执行新增操作
        $set = array(
            'userid' => $userid,
            'type' => $type,
            'folder_hid' => $folder_hid,
            'title_simple' => $title_simple,
            'suffix' => $suffix ? $suffix : '',
            'copy_nums' => $num_add
        );
        $collection_attachment->insert($set);
    }

    return true;
}

function mg_error_handle($errno, $errstr, $errfile, $errline)
{
    ob_clean();
    require_once INTERFACE_PATH . '/lib/Response.class.php';
    Mg()->response->status = 500;
    Mg()->response->msg = $errstr . $errfile . $errline;
    Mg()->response->response();
}

function mg_shunt_down()
{
    $err_info = error_get_last();
    if ($err_info) {
        mg_error_handle($err_info['type'], $err_info['message'], $err_info['file'], $err_info['line']);
    }
}


function createdir($path)
{
    if (! file_exists($path))
    {
        createdir(dirname($path));
        $res = mkdir($path, 0777);
        if (! $res) {
            throw new Exception('createdir '. $path . 'failed', 20001);
        }
    }
}

/**
 * 获取当前毫秒级时间戳
 */
function getMicrotime()
{
    return (int) round(microtime(true) * 1000);
}

/**
 * 毫秒时间戳转日期格式，精确到毫秒，x 表示毫秒
 *
 * @param integer $time 毫秒级时间戳
 * @param string $format 要格式化的时间格式
 * @return string
 */
function formatMicrotime($time, $format = null)
{
    $msec = substr($time, -3);
    $format = $format ? $format : 'Y-m-d H:i:s.x';
    $date = date($format, substr($time, 0, 10));
    return str_replace('x', $msec, $date);
}

/**
 * 格式化时间，格式：00:00:00
 *
 * @param integer $time 要处理的时间，单位：秒
 * @return string
 */
function timeFormat($time)
{
    if ($time < 10) {
        $time = '00:00:0' . $time;
    } elseif ($time < 60) {
        $time = '00:00:' . $time;
    } elseif ($time >= 60 && $time < 3600) {
        $m = floor($time / 60);
        $m = $m >= 10 ? $m : '0' . $m;
        $s = $time % 60;
        $s = $s >= 10 ? $s : '0' . $s;
        $time = '00:' . $m . ':' . $s;
    } elseif ($time >= 3600 && $time < 21600) {
        $h = floor($time / 3600);
        $h = $h >= 10 ? $h : '0' . $h;
        $diff = $time - $h * 3600;
        $m = floor($diff / 60);
        $m = $m >= 10 ? $m : '0' . $m;
        $s = $diff % 60;
        $s = $s >= 10 ? $s : '0' . $s;
        $time = $h . ':' . $m . ':' . $s;
    }
    return $time;
}

/**
 * 生成随机不重复字串
 * m：长度为32位的MD5字串；s：长度为40位的SHA1字串
 *
 * @return string
 */
function getRandomString($length = 'm')
{
    $computer = @$_SERVER["SERVER_NAME"] . '/' . @$_SERVER["SERVER_ADDR"];
    $long = (rand(0, 1) ? '-' : '') . rand(1000, 9999) . rand(1000, 9999) . rand(1000, 9999) . rand(100, 999) . rand(100, 999);
    $microtime = microtime(true);
    return $length == 's' ? sha1($computer . $long . $microtime) : md5($computer . $long . $microtime);
}

/**
 * 图片转格式为 jpg 格式文件
 *
 * @param string $filepath 图片文件地址
 * @return array
 */
function trans2jpg($filepath)
{
    /* 处理需要处理的文件地址 */
    $input = Mg()->config['upload_root_dir'] . $filepath;
    $input = str_replace('//', '/', $input);

    /* 处理输出路径 */
    $filepath_arr = explode('.', $filepath);
    $suffix = strtolower($filepath_arr[count($filepath_arr) - 1]);
    $filepath_arr[count($filepath_arr) - 2] .= '_trans';
    $filepath_arr[count($filepath_arr) - 1] = 'jpg';
    $filepath_new = implode('.', $filepath_arr);
    $output = Mg()->config['upload_root_dir'] . $filepath_new;
    $output = str_replace('//', '/', $output);

    /* 执行 */
    switch ($suffix) {
        case 'jpg':
            $img2 = imagecreatefromjpeg($input);
            break;
        case 'jpeg':
            $img2 = imagecreatefromjpeg($input);
            break;
        case 'png':
            $img2 = imagecreatefrompng($input);
            break;
        case 'bmp':
            $img2 = imagecreatefrombmp($input);
            break;
    }
    imagejpeg($img2, $output);
    imagedestroy($img2);

    return $filepath_new;
}

/**
 * 创建一个bmp图像
 */
function imagecreatefrombmp($filename)
{
    if (!$f1 = fopen($filename, "rb"))
        return FALSE;

    $FILE = unpack("vfile_type/Vfile_size/Vreserved/Vbitmap_offset", fread($f1, 14));
    if ($FILE['file_type'] != 19778)
        return FALSE;

    $BMP = unpack('Vheader_size/Vwidth/Vheight/vplanes/vbits_per_pixel' . '/Vcompression/Vsize_bitmap/Vhoriz_resolution' . '/Vvert_resolution/Vcolors_used/Vcolors_important', fread($f1, 40));
    $BMP['colors'] = pow(2, $BMP['bits_per_pixel']);
    if ($BMP['size_bitmap'] == 0)
        $BMP['size_bitmap'] = $FILE['file_size'] - $FILE['bitmap_offset'];
    $BMP['bytes_per_pixel'] = $BMP['bits_per_pixel'] / 8;
    $BMP['bytes_per_pixel2'] = ceil($BMP['bytes_per_pixel']);
    $BMP['decal'] = ($BMP['width'] * $BMP['bytes_per_pixel'] / 4);
    $BMP['decal'] -= floor($BMP['width'] * $BMP['bytes_per_pixel'] / 4);
    $BMP['decal'] = 4 - (4 * $BMP['decal']);
    if ($BMP['decal'] == 4)
        $BMP['decal'] = 0;

    $PALETTE = array();
    if ($BMP['colors'] < 16777216) {
        $PALETTE = unpack('V' . $BMP['colors'], fread($f1, $BMP['colors'] * 4));
    }

    $IMG = fread($f1, $BMP['size_bitmap']);
    $VIDE = chr(0);

    $res = imagecreatetruecolor($BMP['width'], $BMP['height']);
    $P = 0;
    $Y = $BMP['height'] - 1;
    while ($Y >= 0) {
        $X = 0;
        while ($X < $BMP['width']) {
            if ($BMP['bits_per_pixel'] == 32) {
                $COLOR = unpack("V", substr($IMG, $P, 3));
                $B = ord(substr($IMG, $P, 1));
                $G = ord(substr($IMG, $P + 1, 1));
                $R = ord(substr($IMG, $P + 2, 1));
                $color = imagecolorexact($res, $R, $G, $B);
                if ($color == -1)
                    $color = imagecolorallocate($res, $R, $G, $B);
                $COLOR[0] = $R * 256 * 256 + $G * 256 + $B;
                $COLOR[1] = $color;
            } elseif ($BMP['bits_per_pixel'] == 24)
                $COLOR = unpack("V", substr($IMG, $P, 3) . $VIDE);
            elseif ($BMP['bits_per_pixel'] == 16) {
                $COLOR = unpack("n", substr($IMG, $P, 2));
                $COLOR[1] = $PALETTE[$COLOR[1] + 1];
            } elseif ($BMP['bits_per_pixel'] == 8) {
                $COLOR = unpack("n", $VIDE . substr($IMG, $P, 1));
                $COLOR[1] = $PALETTE[$COLOR[1] + 1];
            } elseif ($BMP['bits_per_pixel'] == 4) {
                $COLOR = unpack("n", $VIDE . substr($IMG, floor($P), 1));
                if (($P * 2) % 2 == 0)
                    $COLOR[1] = ($COLOR[1] >> 4);
                else
                    $COLOR[1] = ($COLOR[1] & 0x0F);
                $COLOR[1] = $PALETTE[$COLOR[1] + 1];
            } elseif ($BMP['bits_per_pixel'] == 1) {
                $COLOR = unpack("n", $VIDE . substr($IMG, floor($P), 1));
                if (($P * 8) % 8 == 0)
                    $COLOR[1] = $COLOR[1] >> 7;
                elseif (($P * 8) % 8 == 1)
                    $COLOR[1] = ($COLOR[1] & 0x40) >> 6;
                elseif (($P * 8) % 8 == 2)
                    $COLOR[1] = ($COLOR[1] & 0x20) >> 5;
                elseif (($P * 8) % 8 == 3)
                    $COLOR[1] = ($COLOR[1] & 0x10) >> 4;
                elseif (($P * 8) % 8 == 4)
                    $COLOR[1] = ($COLOR[1] & 0x8) >> 3;
                elseif (($P * 8) % 8 == 5)
                    $COLOR[1] = ($COLOR[1] & 0x4) >> 2;
                elseif (($P * 8) % 8 == 6)
                    $COLOR[1] = ($COLOR[1] & 0x2) >> 1;
                elseif (($P * 8) % 8 == 7)
                    $COLOR[1] = ($COLOR[1] & 0x1);
                $COLOR[1] = $PALETTE[$COLOR[1] + 1];
            } else
                return FALSE;
            imagesetpixel($res, $X, $Y, $COLOR[1]);
            $X++;
            $P += $BMP['bytes_per_pixel'];
        }
        $Y--;
        $P += $BMP['decal'];
    }
    fclose($f1);

    return $res;
}
